home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SWAG / SWAGA_C / COMM.SWG / 0029_UART Detection.pas < prev    next >
Pascal/Delphi Source File  |  1993-10-28  |  8KB  |  186 lines

  1. {-------------------------------------------------------------------------
  2.  !                                                                       !
  3.  !  UARD.PAS   : Uart Detection Program        Ver 1.0                   !
  4.  !                                                                       !
  5.  !  Created    : 09-23-93        Changed: 09-23-93                       !
  6.  !                                                                       !
  7.  !  Converted To Turbo Pascal 6.0 By: David D. Cruger                    !
  8.  !                                                                       !
  9.  !  Original Program By:      National Semiconductor Corporation         !
  10.  !  NS1655.ZIP                Microcomputer Systems Division             !
  11.  !                            Microcontroller Applications Group         !
  12.  !                            Written By: Louis Shay / 01/11/89          !
  13.  !                            Originaly Written in some form of 'C'.     !
  14.  !                            This program only does the 'detection'.    !
  15.  !                            The original program ran some tests on     !
  16.  !                            the Uarts.                                 !
  17.  !                                                                       !
  18.  !  SAVE/RESTORE Uart Registers Routines from Form Message #195739       !
  19.  !  by Michael Day (TeamB)                                               !
  20.  !                                                                       !
  21.  !  *NOTE*  This program is just an example of how to detect Uarts and   !
  22.  !          is not intended to be a stand alone program.  I here by      !
  23.  !          release this program to the public domain.  Use at your own  !
  24.  !          risk.                                                        !
  25.  !                                                                       !
  26.  !   0: No Uart at Port Address                                          !
  27.  !   1: INS8250, INS8250-B                                               !
  28.  !   2: INS8250A, INS82C50A, NS16450, NS16C450                           !
  29.  !   3: NS16550A                                                         !
  30.  !   4: NS16C552                                                         !
  31.  !                                                                       !
  32.  !------------------------------------------------------------------------}
  33.  
  34. Program UartD;
  35.  
  36.   {
  37.      A =  Align Data
  38.      B =  Boolean Short
  39.      D =  Debug On
  40.      E =  Emulate 80287
  41.      F =  Far Calls
  42.      G =  Generate 286 Code
  43.      L =  Local Symbol Information
  44.      N =  Numeric Processing Switch
  45.      O =  Overlay
  46.      R =  Range Checking On
  47.      S =  Stack-Overflow
  48.      V =  Var-String Checking
  49.   }
  50.  
  51. {$a+,b-,d-,e-,f-,g-,l-,n-,o-,r-,s-,v-}                                 {}
  52. {$M 2500,0,0}
  53.  
  54. Uses Dos;
  55.  
  56. Type Uart_Registers=Array[0..9] OF Byte;  { Uart Registers              }
  57.  
  58. Var  URegs: Uart_Registers;      { Uart Register Array                  }
  59.      PA   : Word;                { Port Address Com1=$3F8  Com2=$2F8..  }
  60.  
  61.      RBR,THR,IER,IIR,FCR,LCR,MCR,LSR,MSR,SCR,DLL,DLM,AFR: Word;
  62.  
  63. {-------- Save Uart Registers --------}
  64. Procedure Save_Uart_Registers(BaseAdd: Word; Var URegs: Uart_Registers);
  65. Var I: Byte;
  66. Begin
  67.   ASM CLI; END;
  68.   For I:=1 to 6 Do URegs[I]:=Port[BaseAdd+I];
  69.   Port[BaseAdd+3]:=Port[BaseAdd+3] or $80;
  70.   URegs[7]:=Port[BaseAdd+0];
  71.   URegs[8]:=Port[BaseAdd+1];
  72.   Port[BaseAdd+3]:=Port[BaseAdd+3] and $7F;
  73.   ASM STI; END;
  74. End; { End Procedure }
  75.  
  76. {------ Restore Uart Registers --------}
  77. Procedure Restore_Uart_Registers(BaseAdd: Word; URegs: Uart_Registers);
  78. Var I: Byte;
  79. Begin
  80.   ASM CLI; END;
  81.   Port[BaseAdd+3]:=Port[BaseAdd+3] or $80;
  82.   Port[BaseAdd+0]:=URegs[7];
  83.   Port[BaseAdd+1]:=URegs[8];
  84.   Port[BaseAdd+3]:=Port[BaseAdd+3] and $7F;
  85.   For I:=1 to 6 Do Port[BaseAdd+I]:=URegs[I];
  86.   ASM STI; END;
  87. End; { End Procedure }
  88.  
  89. Procedure Return_Code(C: Byte);
  90. Begin
  91.  
  92.   Case C of
  93.    0:Writeln('No Uart at Port Address');
  94.    1:Writeln('INS8250, INS8250-B');
  95.    2:Writeln('INS8250A, INS82C50A, NS16450, NS16C450');
  96.    3:Writeln('NS16550A');
  97.    4:Writeln('NS16C552');
  98.    End;
  99.  
  100.    Restore_Uart_Registers(PA,URegs);
  101.  
  102.    Halt(C);  { Halt with Errorlevel of Uart }
  103.  
  104. End; { End Procedure }
  105.  
  106. Procedure Set_Uart_Register_Values(PA: Word);
  107. Begin
  108.  
  109. RBR:=PA+0;         { Receive Buffer Registers          (R  ) (DLAB=0)     }
  110. THR:=PA+0;         { Transmitter Holding Register      (  W) (DLAB=0)     }
  111. IER:=PA+1;         { Interrupt Enable Register         (R/W) (DLAB=0)     }
  112. IIR:=PA+2;         { Interrupt Ident. Register         (R  )              }
  113. FCR:=PA+2;         { FIFO Control Register             (  W)              }
  114. LCR:=PA+3;         { Line Control Register             (R/W)              }
  115. MCR:=PA+4;         { MODEM Control Register            (R/W)              }
  116. LSR:=PA+5;         { Line Status Register              (R  )              }
  117. MSR:=PA+6;         { MODEM Status Register             (R/W)              }
  118. SCR:=PA+7;         { Scratch Register                  (R/W)              }
  119. DLL:=PA+0;         { Divisor Latch (LSB)               (R/W) (DLAB=1)     }
  120. DLM:=PA+1;         { Divisor Latch (MSB)               (R/W) (DLAB=1)     }
  121. AFR:=PA+2;         { Alternate Function Register       (R/W)              }
  122.  
  123. End; { End Procedure }
  124.  
  125. Begin  { Main Section of Program }
  126.  
  127. PA:=$3F8; { Com1/ This can be changed to any port address you want }
  128. Write('Com1: $3F8 : Uart:=');
  129.  
  130. Save_Uart_Registers(PA,URegs);  { Saves State of Current Uart Registers    }
  131. Set_Uart_Register_Values(PA);   { Return_Code() Restores Uart Registers    }
  132.  
  133. Port[LCR]:=$AA;                         { Test LCR Registers               }
  134. If $AA<>Port[LCR] Then Return_Code(0);
  135.  
  136. Port[DLM]:=$55;                         { Test DLM Present 8-bits          }
  137. If $55<>Port[DLM] Then Return_Code(0);
  138.  
  139. Port[LCR]:=$55;                         { LCR/ DLAB=0                      }
  140. If $55<>Port[LCR] Then Return_Code(0);
  141.  
  142. Port[IER]:=$55;                         { Test IER Present 4-bits          }
  143. If $05<>Port[IER] Then Return_Code(0);
  144.  
  145. Port[FCR]:=$0;                          { FIFO's Off, If Present           }
  146. Port[IER]:=$0;                          { Interrupts Off, IIR Should be 01 }
  147. If $1<>Port[IIR] Then Return_Code(0);
  148.  
  149. {----- Test Modem Control Register Address. Should be 5-bits Wide -----}
  150. Port[MCR]:=$F5;                         { 8-bit Write                      }
  151. If $15<>Port[MCR] Then Return_Code(0);
  152.  
  153. {------ Test MCR/MSR Loopback Functions ------}
  154.  
  155. Port[MCR]:=$10;                         { Set Loop Mode                    }
  156. Port[MSR]:=$0;                          { Clear out Delta Bits             }
  157. If ($F0 and Port[MSR])<>0 Then Return_Code(0); { Check State Bits          }
  158.  
  159. Port[MCR]:=$1F;                         { Toggle Modem Control Lines       }
  160. If ($F0 and Port[MSR])<>$F0 Then Return_Code(0); { Check State Bits        }
  161.  
  162. Port[MCR]:=$03;                         { Exit Loop Mode, DTR, RTS Active  }
  163.  
  164. {---- Port Id Successful at this point. determine port type ----}
  165.  
  166. Port[SCR]:=$55;                         { Is There a Scratch Register?    }
  167. If $55<>Port[SCR] Then Return_Code(1);  { No SCR, Type = INS8250          }
  168.  
  169. Port[FCR]:=$CF;                         { Enable FIFO's, If Present       }
  170. If ($C0 and Port[IIR])<>$C0 Then Return_Code(2); { Check FIFO ID bits     }
  171. Port[FCR]:=$0;                          { Turn Off FIFO's                 }
  172.  
  173. Port[LCR]:=$80;                         { Set DLAB                        }
  174. Port[AFR]:=$07;                         { Write to AFR                    }
  175. If $07<>Port[AFR] Then                  { Read AFR                        }
  176.   Begin
  177.     Port[LCR]:=$0;                      { Reset DLAB                      }
  178.     Return_Code(3);                     { If Not Type=NS16550A            }
  179.   End;
  180.  
  181. Port[AFR]:=$0;                          { Clear AFR                       }
  182. Port[LCR]:=$0;                          { Reset DLAB                      }
  183. Return_Code(4);
  184.  
  185. End.
  186.